package com.wmx.java_8.stream;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**********************************
 * @author wmx
 * @date 2019/10/11 14:02
 * @description:
 * @version 1.0
 *
 * java8中引入了java.util.stream这样一个包（流），
 * 新特性的添加旨在能帮助开发人员更高的抽象层次上
 * 对集合进行一系列操作。
 *
 *
 ************************************/
public class StreamDemo {
    public static void main(String[] args) {
        List<Dish> menu = Arrays.asList(
                new Dish("pork", false, 800, Dish.Type.MEAT),
                new Dish("beef", false, 700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH));
        List<String> dishNamesByCollections = getDishNamesByCollections(menu);
        System.out.println(dishNamesByCollections);
        System.out.println(getDishNamesByStream(menu));
        Map<Dish.Type, List<Dish>> collect = menu.stream().collect(Collectors.groupingBy(Dish::getType));
        System.out.println("Collectors.groupingBy:=========>>" + collect);
        Map<String, Integer> collect1 = menu.stream().collect(Collectors.toMap((Dish::getName), (Dish::getCalories)));
        System.out.println("Collectors.toMap:=========>>" + collect1);
        collect1.forEach((k, v) -> System.out.println("key的值：" + k + "   value的值：" + v));
        List<Dish> dishes = collect.get("");
        Optional.ofNullable(dishes).ifPresent(System.out::println);
    }

    /**
     * 通过Collections找到卡路里小于400食物
     *
     * @param menu
     * @return
     */
    private static List<String> getDishNamesByCollections(List<Dish> menu) {
        ArrayList<Dish> lowCalorie = new ArrayList<>();
        for (Dish dish : menu) {
            if (dish.getCalories() < 400) {
                lowCalorie.add(dish);
            }
        }

        //Collections.sort(lowCalorie, (a, b) -> Integer.compare(a.getCalories(), b.getCalories()));
        System.out.println("通过Collections.sort排序" + lowCalorie);
        ArrayList<String> dishesNames = new ArrayList<>();
        for (Dish dish : lowCalorie) {
            dishesNames.add(dish.getName());
        }
        return dishesNames;
    }


    /**
     * 通过Stream找到卡路里小于400的食物
     */
    private static List<String> getDishNamesByStream(List<Dish> menu) {

        Stream stream = menu.stream();
/*
        return menu.stream().filter(a -> a.getCalories() < 400).
                sorted(Comparator.comparing(b -> b.getCalories())).map(b -> b.getName()).collect(toList());*/
        //使用方法推导  Method references【方法推导】
        /**
         *  menu.parallelStream()
         * 并行流 parallelStream 提供了流的并行处理，它是Stream的另一重要特性，
         * 其底层使用Fork/Join框架实现。简单理解就是多线程异步任务的一种实现。
         */
        return menu.stream().filter(a -> a.getCalories() < 400).
                sorted(Comparator.comparing(Dish::getCalories)).map(Dish::getName).collect(toList());

    }

}
